added Feb 2001 SDK
[windows-sources.git] / shared source / wpf / src / host / shimimpl / hostshim.cxx
blob748d3bbe59af4738d07cc22862333789ab693140
1 //------------------------------------------------------------------------
2 //
3 // Copyright (c) Microsoft Corporation. All rights reserved.
4 //
5 // Description:
6 // Implements the minimal set of interfaces required for
7 // the version-independent hosting shim.
8 //
9 // History:
10 // 2005/05/09 - [....]
11 // Created
12 // 2007/09/20 - [....]
13 // Ported Windows->DevDiv. See SourcesHistory.txt.
15 //------------------------------------------------------------------------
17 #include "PreCompiled.hxx"
18 #include "HostShim.hxx"
19 #include "Version.hxx"
20 #include "VersionFactory.hxx"
21 #include "PersistFile.hxx"
22 #include "PersistMoniker.hxx"
23 #include "PersistHistory.hxx"
24 #include "ClassFactory.hxx"
25 #include "ShimUtilities.hxx"
26 #include "Main.hxx"
27 #include "DeploymentManifest.hxx"
28 #include "ApplicationManifest.hxx"
29 #include "MarkupVersion.hxx"
30 #include "WatsonReporting.hxx"
32 #include "..\inc\ShimDllInterface.hxx"
33 #include "..\inc\registry.hxx"
36 #define LATEST_VERSION L"0.0.0"
38 CHostShim* CHostShim::m_pInstance = NULL;
40 CHostShim::CHostShim():
41 m_strErrorMessageToDisplay(24000)
43 m_ObjRefCount = 0;
44 m_pInstance = this;
45 m_pInnerObject = NULL;
46 m_pUnkSite = NULL;
47 m_pVersion = NULL;
48 //
49 m_pPersistMoniker = new CPersistMoniker(this);
50 m_pPersistFile = new CPersistFile(this);
51 m_pPersistHistory = new CPersistHistory(this);
52 m_pOleObjectDelegate = NULL;
53 m_pPendingClientSite = NULL;
54 m_pByteWrapperImpl = NULL;
55 m_pByteRangeDownloaderService = NULL;
56 m_pHistoryStream = m_pDocumentStream = NULL;
57 m_mimeType = MimeType_Unknown;
58 m_bAllowPersistFileLoad = m_bAllowPersistFileLoadSet = false;
59 m_activationType = Unknown;
60 m_bInvokeFrameworkBootstrapper = false;
62 m_hDownloadCompletedEvent = ::CreateEvent(
63 NULL, // Default security, not inherited.
64 TRUE, // Manual reset event.
65 TRUE, // Initially signaled.
66 NULL // No name.
70 CHostShim::~CHostShim()
72 if (m_pVersion && m_pVersion->IsAttached())
74 m_pVersion->Deactivate();
77 m_pInstance = NULL;
79 delete m_pPersistMoniker;
80 delete m_pPersistFile;
81 delete m_pPersistHistory;
83 ReleaseInterface(m_pUnkSite);
85 m_pInstance = NULL;
86 m_pInnerObject = NULL;
87 m_pPersistFile = NULL;
88 m_pPersistHistory = NULL;
89 m_pPersistMoniker = NULL;
90 m_pOleObjectDelegate = NULL;
91 m_pPendingClientSite = NULL;
94 // Do not close m_hDownloadCompletedEvent here, destroy it in DllMain
95 // to avoid race condition.
97 PostQuitMessage(ERROR_SUCCESS);
100 CHostShim* CHostShim::GetInstance()
102 return m_pInstance;
105 CVersion* CHostShim::GetValidVersion()
107 CHostShim* pHostShim = GetInstance();
108 if (!pHostShim)
109 return NULL;
111 CVersion* pVersion = pHostShim->GetVersion();
112 if (!pVersion)
113 return NULL;
115 if (!pVersion->IsValid())
116 return NULL;
118 return pVersion;
121 //******************************************************************************
123 // IUnknown Implementation
125 //******************************************************************************
127 /******************************************************************************
128 CHostShim::QueryInterface
129 ******************************************************************************/
130 STDMETHODIMP CHostShim::QueryInterface( __in_ecount(1) REFIID riid, __deref_out_ecount(1) LPVOID *ppReturn)
132 HRESULT hr = E_NOINTERFACE;
133 CHECK_POINTER(ppReturn);
135 *ppReturn = NULL;
137 if (riid == IID_IUnknown)
139 *ppReturn = (IUnknown*) ((IOleObject*) this);
141 else if (riid == IID_IStdMarshalInfo)
143 *ppReturn = (IStdMarshalInfo*)this;
145 else if (riid == IID_IPersist)
147 // Doesn't matter which persist interface since all of them update
148 // the clsid on the doc and defer the GetClassID call to the doc
149 *ppReturn = (IPersist *) m_pPersistMoniker;
151 else if (riid == IID_IPersistFile)
153 *ppReturn = m_pPersistFile;
155 else if (riid == IID_IPersistMoniker)
157 *ppReturn = m_pPersistMoniker;
160 If marshaling of IPersistMoniker fails, IE will fall back to IPersistFile activation by passing
161 the location of the .xbap file from the cache. This doesn't work because the deployment manifest is
162 separated from the rest of the application. (But it's okay for XPSViewer; hence the conditional
163 compilation.)
165 The registry keys for IPersistMoniker are apparently susceptible to an ACL anomaly similar to that
166 described in WatsonReporting.hxx: There is no entry for the Users group, only Administrators and
167 SYSTEM. Causes are still unknown, but there have been real cases confirmed. Even on some good
168 computers permission inheritance for the main IPersistMoniker key is disabled. This is a likely
169 precondition for the real problem.
171 static bool fTestedMarshaling = false;
172 if(!fTestedMarshaling)
174 fTestedMarshaling = true;
175 CComPtr<IStream> spMonikerStream;
176 if(FAILED(CoMarshalInterThreadInterfaceInStream(IID_IPersistMoniker, m_pPersistMoniker, &spMonikerStream)))
178 TriggerWatson(ActivationProblemIds::IPersistMonikerMarshalingFailed);
180 else
182 CoReleaseMarshalData(spMonikerStream);
186 else if (riid == IID_IPersistHistory)
188 *ppReturn = m_pPersistHistory;
190 else if(riid == IID_IHlinkTarget)
192 if (!GetVersion())
194 *ppReturn = (IHlinkTarget*)this;
197 else if (riid == IID_IOleObject)
199 if (m_bInvokeFrameworkBootstrapper || !GetVersion())
201 *ppReturn = (IOleObject*) this;
203 // else: query inner object [below]
205 else if (riid == IID_IObjectWithSite)
207 *ppReturn = (IObjectWithSite*)this;
210 if (*ppReturn)
212 AddRef();
213 hr = S_OK;
215 else
217 if (m_pInnerObject)
219 return m_pInnerObject->QueryInterface(riid, ppReturn);
222 Cleanup:
223 return hr;
226 /******************************************************************************
227 CHostShim::AddRef
228 ******************************************************************************/
229 STDMETHODIMP_(DWORD) CHostShim::AddRef()
231 return InterlockedIncrement(&m_ObjRefCount);
234 /******************************************************************************
235 CHostShim::Release
236 ******************************************************************************/
237 STDMETHODIMP_(DWORD) CHostShim::Release()
239 DWORD uRefs = InterlockedDecrement(&m_ObjRefCount);
241 if (uRefs == 0)
243 #ifdef DEBUG
244 OutputDebugString(L"CHostShim::Release()\n");
245 #endif
246 delete this;
247 return 0;
250 return uRefs;
253 //******************************************************************************
255 // IStdMarshalInfo Implementation
257 //******************************************************************************
259 // See host\Proxy\BrowserInprocHandler.hxx for explanation of the in-proc handler.
260 HRESULT CHostShim::GetClassForHandler(DWORD dwDestContext, void*, CLSID * pClsid)
262 if(dwDestContext == MSHCTX_LOCAL) // marshaling to another process?
264 *pClsid = CLSID_PresentationHostInprocHandler;
265 return S_OK;
267 return E_FAIL;
270 //******************************************************************************
272 // IObjectWithSite Implementation
274 //******************************************************************************
276 HRESULT CHostShim::SetSite(IUnknown *pUnkSite)
278 ReplaceInterface(m_pUnkSite, pUnkSite);
279 return S_OK;
282 HRESULT CHostShim::GetSite(REFIID riid, /* [iid_is][out] */ void **ppvSite)
284 *ppvSite = 0;
285 if(!m_pUnkSite)
286 return E_FAIL; // per IObjectWithSite specification
287 return m_pUnkSite->QueryInterface(riid, ppvSite);
291 /******************************************************************************
292 CHostShim::GetClassID()
293 ******************************************************************************/
294 STDMETHODIMP CHostShim::GetClassID(__out_ecount(1) LPCLSID pClassID)
296 HRESULT hr = S_OK;
297 CK_PARG(pClassID);
299 *pClassID = *CClassFactory::GetActivatedClsId();
301 Cleanup:
302 return hr;
305 void CHostShim::InvokeFrameworkBootstrapperWithFallback()
307 if(FAILED(InvokeFrameworkBootstrapper()))
309 // Need to set dialog owner window. Otherwise it will appear behind the browser's window.
310 HWND hwnd = 0;
311 CComQIPtr<IOleWindow> spOleWindow(m_pPendingClientSite);
312 if(spOleWindow)
314 spOleWindow->GetWindow(&hwnd);
316 wchar_t prompt[2000];
317 if(LoadResourceString(IDS_GETNETFX, prompt, ARRAYSIZE(prompt)) &&
318 MessageBox(hwnd, prompt, L"Microsoft .NET Framework Setup", MB_ICONQUESTION | MB_OKCANCEL) == IDOK)
320 ShellExecute(hwnd, 0, L"http://go.microsoft.com/fwlink/?linkid=54520", 0, 0, SW_SHOW);
325 // WinFxDocObj is the .NET Framework bootstrapper that ships with IE (for Windows version before Windows 7).
326 // It's registered and invoked as a DocObject. It only needs to be driven to the IOleObject::DoVerb() step.
327 HRESULT CHostShim::InvokeFrameworkBootstrapper()
329 HRESULT hr = S_OK;
330 CComPtr<IOleObject> spBootstrapper;
331 CComPtr<IBindCtx> spBindCtx;
332 CComPtr<IMoniker> spMoniker;
333 CComQIPtr<IPersistMoniker> spMonikerLoader;
334 CComQIPtr<IPersistFile> spFileLoader;
335 CComPtr<IWebBrowser2> spWebBrowser;
337 // WinFxDocObj works only in IE - it needs the IWebBrowser2. Fail if this is not IE.
338 ASSERT(m_pPendingClientSite);
339 CKHR(QueryService(m_pPendingClientSite, SID_SWebBrowserApp, IID_IWebBrowser2, (void**)&spWebBrowser));
341 CKHR(spBootstrapper.CoCreateInstance(L"Bootstrap.XBAP"));
342 // WinFxDocObj uses the client site to get the browser's window.
343 // Quirk: It does this when the client site is reset to null (using the previous reference).
344 spBootstrapper->SetClientSite(m_pPendingClientSite);
345 spBootstrapper->SetClientSite(0);
347 // Pass the startup URL via IPersistMoniker or IPersistFile.
348 // Like PresentationHost, WinFxDoc fails IPeristMoniker::Load() for file:// URLs. Just like IE, try
349 // IPersistFile then. Note that calling IPersistMoniker first is needed because that's where WinFxDocObj
350 // captures the URL to use it later.
351 CKHR(CreateURLMonikerEx(0, m_strStartupUri.GetValue(), &spMoniker, URL_MK_UNIFORM));
352 spMonikerLoader = spBootstrapper; //QI
353 if(!spMonikerLoader)
354 CKHR(E_NOINTERFACE);
355 CKHR(CreateBindCtx(0, &spBindCtx));
356 hr = spMonikerLoader->Load(false, spMoniker, spBindCtx, 0);
357 if(hr != S_OK)
359 if(hr == S_FALSE)
361 hr = E_FAIL;
363 spFileLoader = spBootstrapper; //QI
364 if(spFileLoader && spFileLoader->Load(m_strStartupUri.GetValue(), 0) == S_OK)
365 hr = S_OK;
366 //else: the result of IPeristMoniker::Load() will be returned/logged.
368 CKHR(hr);
370 CKHR(spBootstrapper->DoVerb(0, 0, m_pPendingClientSite, 0, 0, 0));
372 Cleanup:
373 return hr;
376 /******************************************************************************
377 CHostShim::Execute
378 Invokes Watson and terminates on any failure.
379 ******************************************************************************/
380 void CHostShim::Execute()
382 DPF(8, _T("CHostShim::Execute"));
383 HRESULT hr = S_OK;
385 // If we don't have a version object yet...
386 if (!m_pVersion)
388 // If the requested version hasn't been set yet...
389 if (!this->GetRequestedVersion())
391 // Get the requested version
392 CKHR(DetermineRequestedVersion());
395 // Get the version object
396 m_pVersion = CVersionFactory::GetVersion(this->GetRequestedVersion());
399 // Since GetVersion() falls back to latest version if the requested one is not available, the likeliest
400 // reason to get nothing here is that there is no SxS version available. (Only PresentationHost.exe
401 // left behind as a shared, permanent component.) Then we try to invoke the WinFxDocObj bootstrapper.
402 // Since it's not available starting from Windows 7, fallback is a message box.
403 if(!m_pVersion)
405 // We need the IOleClientSite to make WinFxDocObj work. So, let the browser keep going with the
406 // activation...
407 m_bInvokeFrameworkBootstrapper = true;
409 // We have a version object, so if it is unattached, try to attach to it
410 else if (!m_pVersion->IsAttached())
412 // Displaying an error message via PHDLL is new for v4 and v3.5 SP1 on Windows 7. Unfortunately, we did
413 // not account for the possibility of PH v4 finding only PHDLL v3 available and an older one that doesn't
414 // have the support for displaying an error message. This can happen if v4 is installed and then uninstalled.
415 // As a shared component, PH.exe is only rolled forward. If we proceed in such case, PHDLL will flounder
416 // for a while and eventually crash, in a very undebuggable way. To prevent this, do a timestamp check and
417 // fall back to a plain message box (which, unfortunately, tends to pop behind the browser window--no owner.)
418 // The assumption is that any (re)release of PHDLL v3 in 2009 or later will have the feature.
419 if(m_strErrorMessageToDisplay.GetValue() && m_pVersion->Major() == 3)
421 WIN32_FILE_ATTRIBUTE_DATA fileInfo;
422 SYSTEMTIME fileTime;
423 if(GetFileAttributesEx(m_pVersion->GetLibraryPath(), GetFileExInfoStandard, &fileInfo) &&
424 FileTimeToSystemTime(&fileInfo.ftLastWriteTime, &fileTime))
426 if(fileTime.wYear < 2009)
428 MessageBeep((UINT)-1);
429 MessageBox(0, m_strErrorMessageToDisplay.GetValue(), CComBSTR(TARGETNAME), MB_ICONERROR);
430 return;
435 CKHR(m_pVersion->Attach());
437 ActivateParameters parameters;
438 parameters.dwSize = sizeof(parameters);
439 parameters.pOuterObject = (LPUNKNOWN) ((LPOLEOBJECT) this);
440 parameters.pswzUri = GetStartupUri();
441 parameters.pswzDebugSecurityZoneURL = g_pswzDebugSecurityZoneURL;
442 parameters.pswzApplicationIdentity = GetApplicationIdentity();
443 parameters.mime = GetMimeType();
444 parameters.pHistoryStream = GetHistoryStream();
445 parameters.pDocumentStream = GetDocumentStream();
446 parameters.hDownloadCompletedEvent = GetDownloadCompletedEvent();
447 parameters.isDebug = g_dwCommandLineFlags & FLAG_DEBUG;
448 parameters.pPersistHistory = (IPersistHistory*) m_pPersistHistory;
449 parameters.hNoHostTimer = g_hNoHostTimer_shim;
450 parameters.pswzErrorMessageToDisplay = m_strErrorMessageToDisplay.GetValue();
452 m_pVersion->Activate(&parameters, &m_pInnerObject); //[Watson on failure]
454 if (GetActivationType() != FileActivation && GetActivationType() != MonikerActivation)
456 IOleObject* pOleObject = NULL;
457 CKHR(m_pInnerObject->QueryInterface(IID_IOleObject, (LPVOID*)&pOleObject));
458 pOleObject->Release(); // we don't want to addref this because we actually aggregate it.
459 SetOleObjectDelegate(pOleObject);
463 Cleanup:
464 HANDLE_ACTIVATION_FAULT(hr);
467 HRESULT CHostShim::SaveToHistory(__in_ecount(1) IStream* pHistoryStream)
469 return m_pVersion->SaveToHistory(pHistoryStream);
472 HRESULT CHostShim::LoadFromHistory(__in_ecount(1) IStream* pHistoryStream, __in_ecount(1) IBindCtx* pBindCtx)
474 return m_pVersion->LoadFromHistory(pHistoryStream, pBindCtx);
478 //******************************************************************************
480 // IHlinkTarget Implementation
482 //******************************************************************************
484 /******************************************************************************
485 CHostShim::SetBrowseContext()
486 ******************************************************************************/
487 STDMETHODIMP CHostShim::SetBrowseContext(__in_ecount_opt(1) IHlinkBrowseContext *pihlbc)
489 return E_NOTIMPL;
492 /******************************************************************************
493 CHostShim::GetBrowseContext()
494 ******************************************************************************/
495 STDMETHODIMP CHostShim::GetBrowseContext(__deref_out_ecount(1) IHlinkBrowseContext **ppihlbc)
497 if(ppihlbc)
499 *ppihlbc = NULL;
501 return E_NOTIMPL;
504 /******************************************************************************
505 CHostShim::Navigate()
506 ******************************************************************************/
507 STDMETHODIMP CHostShim::Navigate(DWORD grfHLNF,__in_ecount_opt(INTERNET_MAX_URL_LENGTH+1) LPCWSTR pwzUri)
509 HRESULT hr = S_OK;
510 SetStartupLocation(pwzUri);
512 if (!GetVersion()) // We haven't been QI'ed for IOleObject yet
514 CKHR(InvokeBrowser(GetStartupUri()));
515 PostQuitMessage(ERROR_SUCCESS);
518 Cleanup:
519 if (FAILED(hr))
521 PostQuitMessage(ERROR_INVOKING_BROWSER);
523 return hr;
526 /******************************************************************************
527 CHostShim::GetMoniker()
528 ******************************************************************************/
529 STDMETHODIMP CHostShim::GetMoniker(__in_ecount(1) LPCWSTR pwzLocation, DWORD dwAssign, __deref_out_ecount(1) IMoniker **ppimkLocation)
531 if (ppimkLocation)
533 *ppimkLocation = NULL;
535 return E_NOTIMPL;
538 /******************************************************************************
539 CHostShim::GetFriendlyName()
540 ******************************************************************************/
541 STDMETHODIMP CHostShim::GetFriendlyName(__in_ecount(1) LPCWSTR pwzLocation, __deref_out_ecount(1) LPWSTR *ppwzFriendlyName)
543 if(ppwzFriendlyName)
545 *ppwzFriendlyName = NULL;
547 return E_NOTIMPL;
550 /******************************************************************************
551 CHostShim::DetermineRequestedVersion()
553 This is where we attempt to determine the requested version.
554 For right now we are using a registry lookup hack to determine what version
555 of Avalon an app requires. Eventually, this information will be obtained
556 from the deployment manifest.
557 ******************************************************************************/
558 HRESULT CHostShim::DetermineRequestedVersion()
560 HRESULT hr = S_OK;
562 if(m_strErrorMessageToDisplay.GetValue())
564 // We are going to activate the DLL just for its error page.
565 SetRequestedVersion(LATEST_VERSION);
566 return S_OK;
569 // To ensure that as much code as possible is tested as often as possible,
570 // disable the optimization below for debug builds.
571 // Also disabled when profiling based on a registry setting.
572 bool fSingleVersionShortcut = true;
573 #ifdef DEBUG
574 fSingleVersionShortcut = false;
575 #else
576 if(ETW_ENABLED_CHECK(TRACE_LEVEL_INFORMATION))
578 DWORD dw;
579 ::GetRegistryDWORD(HKEY_LOCAL_MACHINE, RegKey_WPF_Hosting, RegValue_DisableSingleVersionOptimization, /*out*/dw, 0);
580 fSingleVersionShortcut = !dw;
582 #endif
584 if (m_mimeType == MimeType_Application)
586 CDeploymentManifest deploymentManifest(GetStartupUri(), GetLocalDeploymentManifestPath());
587 hr = deploymentManifest.Read();
589 if (SUCCEEDED(hr))
591 SetApplicationIdentity(deploymentManifest.GetApplicationIdentity());
593 if (fSingleVersionShortcut && CVersionFactory::GetCount() == 1)
595 // If there is only one version of Avalon installed, there isn't any point
596 // in checking the application manifest
597 CKHR(SetRequestedVersion(LATEST_VERSION));
599 else
601 CApplicationManifest applicationManifest(GetStartupUri(), deploymentManifest.GetApplicationManifestCodebase());
602 applicationManifest.AddRef(); // need to do this because msxml will addref and release, and we still need it
604 hr = applicationManifest.Read();
606 if (SUCCEEDED(hr))
608 //TEMP WORKAROUND for putting reference to WindowsBase v3 in the app manifest.
609 // (This is done so that the PolicyLevel can be resolved correctly with the additional
610 // permissions we put under HKLM\SOFTWARE\Microsoft\.NETFramework\Security\Policy\Extensions\NamedPermissionSets,
611 // which are still v3 for bkw compatibility.)
612 CVersion ver(applicationManifest.GetRequestedVersion());
613 CVersion verCLR(applicationManifest.GetRequestedClrVersion());
614 const CVersion *pLargerVersion = &ver;
615 if(ver.CompareTo(&verCLR) < 0)
617 pLargerVersion = &verCLR;
620 hr = SetRequestedVersion(pLargerVersion->GetValue());
625 if (FAILED(hr))
627 CKHR(SetRequestedVersion(LATEST_VERSION));
630 else if (m_mimeType == MimeType_Markup)
632 if (fSingleVersionShortcut && CVersionFactory::GetCount() == 1)
634 // If there is only one version of Avalon installed, there isn't any point
635 // in checking the application manifest
636 CKHR(SetRequestedVersion(LATEST_VERSION));
638 else
640 CMarkupVersion markupVersion(GetLocalDeploymentManifestPath());
641 markupVersion.AddRef(); // need to do this because msxml will addref and release, and we still need it
643 // We don't actually care what the HRESULT is since an error indicates that we are done parsing the XAML
644 // file and we should just go with whatever we have even if there was some other error.
645 (void) markupVersion.Read();
647 // Get the highest version for the namespaces that we have (ignorable or not.)
648 CVersion* pHighestVersion = NULL;
649 CStringMap<CString*>::CStringMapNode* pPrefixNamespaceNode = markupVersion.GetPrefixNamespaces().GetRoot();
650 while (pPrefixNamespaceNode)
652 CString* pStrNamespace = pPrefixNamespaceNode->GetValue();
653 CString* pStrVersion = NULL;
655 if (SUCCEEDED(markupVersion.GetNamespaceVersion().Find(pStrNamespace->GetValue(), &pStrVersion)))
657 CVersion* pVersion = CVersionFactory::GetVersion(pStrVersion->GetValue(), FALSE);
659 if (pVersion && (pHighestVersion == NULL || pHighestVersion->CompareTo(pVersion) < 0))
661 pHighestVersion = pVersion;
664 else
666 ASSERT(FALSE); // Should always have been able to find the version number.
669 pPrefixNamespaceNode = pPrefixNamespaceNode->GetNext();
672 if (pHighestVersion)
674 CKHR(SetRequestedVersion(pHighestVersion->GetValue()));
676 else
678 CKHR(SetRequestedVersion(LATEST_VERSION));
682 else
684 // Bad MIME-type
685 ASSERT(FALSE);
686 CKHR(E_FAIL);
689 Cleanup:
690 return hr;
693 //-----------------------------------------------------------------------------
694 // IOleObject and related methods
695 //-----------------------------------------------------------------------------
697 void CHostShim::SetOleObjectDelegate(IOleObject* pOleObjectDelegate)
699 m_pOleObjectDelegate = pOleObjectDelegate;
700 if (m_pPendingClientSite)
702 m_pOleObjectDelegate->SetClientSite(m_pPendingClientSite);
703 m_pPendingClientSite->Release();
707 STDMETHODIMP CHostShim::SetClientSite(__in LPOLECLIENTSITE pClientSite)
709 if (m_pOleObjectDelegate)
711 return m_pOleObjectDelegate->SetClientSite(pClientSite);
713 else
715 ReplaceInterface(m_pPendingClientSite, pClientSite);
717 if(m_bInvokeFrameworkBootstrapper && pClientSite)
719 InvokeFrameworkBootstrapperWithFallback();
720 return E_FAIL;
723 return S_OK;
727 STDMETHODIMP CHostShim::Advise(__in LPADVISESINK pAdvSink, __out LPDWORD pdwConnection)
729 return m_pOleObjectDelegate ? m_pOleObjectDelegate->Advise(pAdvSink, pdwConnection) : E_NOTIMPL;
732 STDMETHODIMP CHostShim::SetHostNames(LPCOLESTR szContainerApp, LPCOLESTR szCOntainerObj)
734 return m_pOleObjectDelegate ? m_pOleObjectDelegate->SetHostNames(szContainerApp, szCOntainerObj) : E_NOTIMPL;
737 STDMETHODIMP CHostShim::DoVerb(LONG iVerb, __in_opt LPMSG lpMsg, __in LPOLECLIENTSITE pActiveSite, LONG lIndex, HWND hwndParent, LPCRECT lprcPosRect)
739 return m_pOleObjectDelegate ? m_pOleObjectDelegate->DoVerb(iVerb, lpMsg, pActiveSite, lIndex, hwndParent, lprcPosRect) : E_NOTIMPL;
742 STDMETHODIMP CHostShim::GetExtent(DWORD dwDrawAspect, LPSIZEL psizel)
744 return m_pOleObjectDelegate ? m_pOleObjectDelegate->GetExtent(dwDrawAspect, psizel) : E_NOTIMPL;
747 STDMETHODIMP CHostShim::Update()
749 return m_pOleObjectDelegate ? m_pOleObjectDelegate->Update() : E_NOTIMPL;
752 STDMETHODIMP CHostShim::Close(DWORD dwSaveOption)
754 return m_pOleObjectDelegate ? m_pOleObjectDelegate->Close(dwSaveOption) : E_NOTIMPL;
757 STDMETHODIMP CHostShim::Unadvise(DWORD dwToken)
759 return m_pOleObjectDelegate ? m_pOleObjectDelegate->Unadvise(dwToken) : E_NOTIMPL;
762 STDMETHODIMP CHostShim::EnumVerbs(LPENUMOLEVERB* ppEnumOleVerb)
764 return m_pOleObjectDelegate ? m_pOleObjectDelegate->EnumVerbs(ppEnumOleVerb) : E_NOTIMPL;
767 STDMETHODIMP CHostShim::GetClientSite(__out LPOLECLIENTSITE* ppClientSite)
769 return m_pOleObjectDelegate ? m_pOleObjectDelegate->GetClientSite(ppClientSite) : E_NOTIMPL;
772 STDMETHODIMP CHostShim::SetMoniker(DWORD dwWhichMoniker, LPMONIKER pmk)
774 return m_pOleObjectDelegate ? m_pOleObjectDelegate->SetMoniker(dwWhichMoniker, pmk) : E_NOTIMPL;
777 STDMETHODIMP CHostShim::GetMoniker(DWORD dwAssign, DWORD dwWhichMoniker, __out LPMONIKER* ppmk)
779 return m_pOleObjectDelegate ? m_pOleObjectDelegate->GetMoniker(dwAssign, dwWhichMoniker, ppmk) : E_NOTIMPL;
782 STDMETHODIMP CHostShim::InitFromData(LPDATAOBJECT pDataObject, BOOL fCreation, DWORD dwReserved)
784 return m_pOleObjectDelegate ? m_pOleObjectDelegate->InitFromData(pDataObject, fCreation, dwReserved) : E_NOTIMPL;
787 STDMETHODIMP CHostShim::GetClipboardData(DWORD dwReserved, __out LPDATAOBJECT* ppDataObject)
789 return m_pOleObjectDelegate ? m_pOleObjectDelegate->GetClipboardData(dwReserved, ppDataObject) : E_NOTIMPL;
792 STDMETHODIMP CHostShim::IsUpToDate()
794 return m_pOleObjectDelegate ? m_pOleObjectDelegate->IsUpToDate() : S_OK;
797 STDMETHODIMP CHostShim::GetUserClassID(__out CLSID* pclsId)
799 return m_pOleObjectDelegate ? m_pOleObjectDelegate->GetUserClassID(pclsId) : E_NOTIMPL;
802 STDMETHODIMP CHostShim::GetUserType(DWORD dwFormOfType, __out LPOLESTR* pszUserType)
804 return m_pOleObjectDelegate ? m_pOleObjectDelegate->GetUserType(dwFormOfType, pszUserType) : E_NOTIMPL;
807 STDMETHODIMP CHostShim::SetExtent(DWORD dwDrawAspect, LPSIZEL psizel)
809 return m_pOleObjectDelegate ? m_pOleObjectDelegate->SetExtent(dwDrawAspect, psizel) : E_NOTIMPL;
812 STDMETHODIMP CHostShim::EnumAdvise(__out LPENUMSTATDATA* ppenumAdvise)
814 return m_pOleObjectDelegate ? m_pOleObjectDelegate->EnumAdvise(ppenumAdvise) : E_NOTIMPL;
817 STDMETHODIMP CHostShim::GetMiscStatus(DWORD dwAspect, __out LPDWORD pdwStatus)
819 if (m_pOleObjectDelegate)
821 return m_pOleObjectDelegate->GetMiscStatus(dwAspect, pdwStatus);
823 else
825 *pdwStatus = OLEMISC_SETCLIENTSITEFIRST;
826 return S_OK;
830 STDMETHODIMP CHostShim::SetColorScheme(LPLOGPALETTE pLogPal)
832 return m_pOleObjectDelegate ? m_pOleObjectDelegate->SetColorScheme(pLogPal) : S_OK;